﻿using System;
using System.Collections.Generic;

namespace DataCoreTechnologies.SqlServer
{
   /// <summary>
   /// Represents the object this trigger is run against.
   /// </summary>
   public enum TriggerOwner
   {
     Undefined,
     Database,
     Table,
     View
   }
   /// <summary>
   /// Represents the type of code this trigger runs.
   /// </summary>
   public enum TriggerType
   {
     Undefined,
     CLRTrigger,
     SqlTrigger
   }
   /// <summary>
   /// Contains information about a trigger that is run against it's parent object.
   /// </summary>
   public sealed class Trigger
   {
      #region Public
      //Properties
      /// <summary>
      /// A number that uniquely identifies this class instance.
      /// </summary>
      public Guid InstanceId { get; private set; }
      /// <summary>
      /// The database this trigger is run against.
      /// </summary>
      public Database Database { get; private set; }
      /// <summary>
      /// The table this trigger is run against.
      /// </summary>
      public Table Table { get; private set; }
      /// <summary>
      /// The view this trigger is run against.
      /// </summary>
      public View View { get; private set; }
      /// <summary>
      /// A title used to identify this trigger within the database.
      /// </summary>
      public string Name { get; internal set; }
      /// <summary>
      /// A short description explaining the purpose of this trigger.
      /// </summary>
      public string Description { get; internal set; }
      /// <summary>
      /// The object this trigger is run against.
      /// </summary>
      public TriggerOwner TriggerOwner { get; internal set; }
      /// <summary>
      /// The type of code this trigger runs.
      /// </summary>
      public TriggerType TriggerType { get; internal set; }
      /// <summary>
      /// The date this trigger was created.
      /// </summary>
      public DateTime CreateDate { get; internal set; }
      /// <summary>
      /// The last time this trigger was changed.
      /// </summary>
      public DateTime ModifyDate { get; internal set; }
      /// <summary>
      /// Indicator stating whether this trigger was created by the system or a user.
      /// </summary>
      public Boolean IsMicrosoftShipped { get; internal set; }
      /// <summary>
      /// Indicator stating if this trigger has been disabled.
      /// </summary>
      public Boolean IsDisabled { get; internal set; }
      /// <summary>
      /// Indicator stating if this trigger is run instead of the code that caused it to fire.
      /// </summary>
      public Boolean IsInsteadOfTrigger { get; internal set; }
      /// <summary>
      /// Indicator stating this trigger is run when a delete statement is run against its parent object.
      /// </summary>
      public Boolean IsDelete { get; internal set; }
      /// <summary>
      /// Indicator stating this trigger is run when a insert statement is run against its parent object.
      /// </summary>
      public Boolean IsInsert { get; internal set; }
      /// <summary>
      /// Indicator stating this trigger is run when a update statement is run against its parent object.
      /// </summary>
      public Boolean IsUpdate { get; internal set; }
      /// <summary>
      /// Returns a full T-Sql statement containing the code to create this trigger.
      /// </summary>
      public string DDL { get; internal set; }
      /// <summary>
      /// Returns a set of lines containing the code to create this trigger.
      /// </summary>
      public IEnumerable<string> CodeLines
      {
         get
         {
             for (int index = 0; index < _codeLines.Count; index++)
             {
                 yield return _codeLines[index];
             }
         }
      }
      /// <summary>
      /// A collection of name / value pairs associated with this trigger.
      /// </summary>
      public IEnumerable<ExtendedProperty> ExtendedProperties
      {
         get
         {
             for (int index = 0; index < _extendedProperties.Count; index++)
             {
                 yield return _extendedProperties[index];
             }
         }
      }
      //Methods
      /// <summary>
      /// Returns a list of T-Sql tokens used to collectively outline the create statement for this trigger.
      /// </summary>
      /// <returns></returns>
      public List<string> GetDdlTokens() { return TSql.GetDDLTokens(DDL); }
      #endregion
      #region Internal
      //Constructors
      /// <summary>
      /// Creates an instance of a trigger and associates it with the table specified by the parameter.
      /// </summary>
      /// <param name="container">The table this trigger is run against.</param>
      internal Trigger(Table container)
      {
         Table = container;
         InstanceId = System.Guid.NewGuid();
      }
      /// <summary>
      /// Creates an instance of a trigger and associates it with the view specified by the parameter.
      /// </summary>
      /// <param name="container">The view this trigger is run against.</param>
      internal Trigger(View container)
      {
         View = container;
         InstanceId = System.Guid.NewGuid();
      }
      /// <summary>
      /// Creates an instance of a database and associates it with the table specified by the parameter.
      /// </summary>
      /// <param name="container">The database this trigger is run against.</param>
      internal Trigger(Database container)
      {
         Database = container;
         InstanceId = System.Guid.NewGuid();
      }
      //Properties
      /// <summary>
      /// A number used to uniquely identify this trigger within the database.
      /// </summary>
      internal int Id { get; set; }
      //Methods
      /// <summary>
      /// Adds a line of code to this trigger.
      /// </summary>
      /// <param name="codeLine"></param>
      internal void AddCodeLine(string codeLine) { _codeLines.Add(codeLine); }
      /// <summary>
      /// Associates a extended property with this trigger.
      /// </summary>
      /// <param name="extendedProperty">The trigger this extended property is associated with.</param>
      internal void AddExtendedProperty(ExtendedProperty extendedProperty) { _extendedProperties.Add(extendedProperty); }
      #endregion
      #region Private
      //Properties
      private List<string> _codeLines = new List<string>();
      private List<ExtendedProperty> _extendedProperties = new List<ExtendedProperty>();
      #endregion
   }
}
